package com.xiaobingby.admin.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaobingby.admin.sys.dto.UserDetailsDto;
import com.xiaobingby.admin.sys.entity.Permission;
import com.xiaobingby.admin.sys.entity.RolePermission;
import com.xiaobingby.admin.sys.mapper.PermissionMapper;
import com.xiaobingby.admin.sys.mapper.RolePermissionMapper;
import com.xiaobingby.admin.sys.service.IPermissionService;
import com.xiaobingby.admin.sys.vo.MenuMeta;
import com.xiaobingby.admin.sys.vo.MenuTreeVo;
import com.xiaobingby.admin.sys.vo.PermissionTreeVo;
import com.xiaobingby.common.util.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * sys_permission 权限表 服务实现类
 * </p>
 *
 * @author XiaoBingBy
 * @since 2018-10-29
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    /**
     * 构造后台菜单Tree
     *
     * @return
     */
    public List<PermissionTreeVo> getPermissionTree() {
        ArrayList<PermissionTreeVo> permissionTreeVos = new ArrayList<>();
        QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
        List<Permission> permissions = permissionMapper.selectList(queryWrapper);
        for (Permission permission : permissions) {
            if (permission.getPid() == 0) {
                PermissionTreeVo permissionTreeVo = new PermissionTreeVo();
                BeanUtils.copyProperties(permission, permissionTreeVo);
                genPermissionTreeVo(permissionTreeVo, permissions);
                permissionTreeVos.add(permissionTreeVo);
            }
        }
        return permissionTreeVos;
    }

    /**
     * 构造角色权限展示Tree
     *
     * @return
     */
    public List<PermissionTreeVo> getRolePermissionTree(Long roleId) {
        // 查询角色拥有权限ID
        QueryWrapper<RolePermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", roleId);
        List<RolePermission> rolePermissions = rolePermissionMapper.selectList(queryWrapper);
        List<PermissionTreeVo> permissionTree = this.getPermissionTree();
        rolePermissions.forEach(rolePermission -> {
            modifyPermissionTreeVo(rolePermission, permissionTree);
        });
        modifyPermissionTreeVo(permissionTree);
        return permissionTree;
    }

    /**
     * 修改是否选中节点属性
     *
     * @param item
     * @param permissionTree
     */
    private void modifyPermissionTreeVo(RolePermission rolePermissions, List<PermissionTreeVo> permissionTree) {
        permissionTree.forEach(item -> {
            if (rolePermissions.getPermissionId() == item.getId()) {
                item.setChecked(true);
                return;
            }
            if (item.getChildren() != null) {
                this.modifyPermissionTreeVo(rolePermissions, item.getChildren());
            }
        });
    }

    /**
     * 修改所有节点数据
     *
     * @param permissionTree
     */
    private void modifyPermissionTreeVo(List<PermissionTreeVo> permissionTree) {
        permissionTree.forEach(item -> {
            item.setExpand(true);
            if (item.getChildren() != null) {
                this.modifyPermissionTreeVo(item.getChildren());
            }
        });
    }

    /**
     * 递归遍历节点
     *
     * @param permissionTreeVo
     * @param permissions
     */
    private void genPermissionTreeVo(PermissionTreeVo permissionTreeVo, List<Permission> permissions) {
        ArrayList<PermissionTreeVo> permissionTreeVos = new ArrayList<>();
        for (Permission permission : permissions) {
            if (permissionTreeVo.getId() == permission.getPid()) {
                PermissionTreeVo temp = new PermissionTreeVo();
                BeanUtils.copyProperties(permission, temp);
                genPermissionTreeVo(temp, permissions);
                permissionTreeVos.add(temp);
            }
        }
        permissionTreeVo.setChildren(permissionTreeVos);
    }

    /**
     * 构造用户前端菜单
     *
     * @return
     */
    @Override
    public List<MenuTreeVo> getUserMenuTree() {
        UserDetailsDto userDetails = SecurityUtils.getUserDetails();
        List<Permission> userMenus = permissionMapper.findUserMenus(userDetails.getId());
        ArrayList<MenuTreeVo> menuTreeVos = new ArrayList<>();
        // 构造一级菜单
        userMenus.forEach(item -> {
            if (item.getPid() == 0) {
                GenOneMenuTreeVo(menuTreeVos, item);
            }
        });

        // 构造二级菜单
        menuTreeVos.forEach(i -> {
            ArrayList<MenuTreeVo> subMenuTreeVos = new ArrayList<>();
            userMenus.forEach(j -> {
                if (i.getId() == j.getPid()) {
                    GenOneMenuTreeVo(subMenuTreeVos, j);
                }
            });
            i.setChildren(subMenuTreeVos);
        });
        return menuTreeVos;
    }

    /**
     * Permission To ArrayList<MenuTreeVo> menuTreeVos
     *
     * @param menuTreeVos
     * @param item
     */
    private void GenOneMenuTreeVo(ArrayList<MenuTreeVo> menuTreeVos, Permission item) {
        MenuTreeVo menuTreeVo = new MenuTreeVo();
        menuTreeVo.setId(item.getId());
        menuTreeVo.setPath(item.getPath());
        menuTreeVo.setName(item.getName());
        menuTreeVo.setComponent(item.getComponent());
        MenuMeta menuMeta = new MenuMeta();
        menuMeta.setTitle(item.getTitle());
        menuMeta.setIcon(item.getIcon());
        menuMeta.setHideInBread(item.getHideInBread() == 0 ? false : true);
        menuMeta.setHideInMenu(item.getHideInMenu() == 0 ? false : true);
        menuMeta.setNotCache(item.getNotCache() == 0 ? false : true);
        menuTreeVo.setMeta(menuMeta);
        menuTreeVos.add(menuTreeVo);
    }

}
